package org.ndot.java.lang.ref;

import java.lang.ref.PhantomReference;
import java.lang.ref.Reference;
import java.lang.ref.ReferenceQueue;
import java.lang.ref.SoftReference;
import java.lang.ref.WeakReference;

import org.junit.Test;

/**
 * @公司名称: 小蚂蚁学堂
 * 
 * @项目名称: J2SE_Study
 * 
 * @类名名称: org.ndot.java.lang.ref.ReferenceTest.java
 * 
 * @作者姓名: SunJincheng
 * 
 * @软件版本: v1.0
 * 
 * @创建日期: 2010-4-13下午02:59:32
 */
public class ReferenceTest {

	public ReferenceTest() {

	}

	@Test
	public void test2() {
		MyDate date = new MyDate();
		date = null;
		// 当不执行 drainMemory() 时候 运行程序<无任何输出>，这是因为：
		// 解释：date虽然被置位null，但由于JVM没有执行垃圾回收操作，MyDate的finalize()方法没有被运行
		drainMemory();
		// 总结：JVM的垃圾回收机制，在内存充足的情况下，除非你显式调用System.gc()，否则它不会进行垃圾回收；在内存不足的情况下，垃圾回收将自动运行
	}

	@Test
	public void test() {
		MyDate date = new MyDate();
		date = null;

	}

	@Test
	public void test3() {
		// 强引用
		MyDate date = new MyDate();
		System.gc();
	}

	@Test
	public void test4() {
		// 软引用
		SoftReference ref = new SoftReference(new MyDate());
		// 让软引用工作
		drainMemory();
		// 解释：在内存不足时，软引用被终止

	}

	@Test
	public void test5() {
		// 弱引用
		WeakReference ref = new WeakReference(new MyDate());
		// 让弱引用工作
		System.gc();
		// 解释：在JVM垃圾回收运行时，弱引用被终止
	}

	@Test
	public void test6() {
		// 假象
		ReferenceQueue queue = new ReferenceQueue();
		PhantomReference ref = new PhantomReference(new MyDate(), queue);
		System.gc(); // 让假象引用工作
		/*
		 * 解释：假象引用，在实例化后，就被终止了，等同于： MyDate date = new MyDate(); date = null;
		 * 终止点，在实例化后，不是在gc时，也不是在内存不足时
		 */
		Reference<MyDate> r = queue.poll();
		if (null != r)
			System.out.println(((MyDate) r.get()).toString());
		else
			System.out.println("Null ...");
	}

	public void drainMemory() {
		// 消耗大量内存，一般迫使JVM进行垃圾回收
		String[] array = new String[1024 * 10];
		for (int i = 0; i < 1024 * 10; i++) {
			for (int j = 'a'; j <= 'z'; j++) {
				array[i] += (char) j;
			}
		}
	}

}
